home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Online / SpeakFreely / src / audio_hp.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  7KB  |  283 lines

  1. /*
  2.  * Hewlett-Packard Audio Support - by Marc Kilian
  3.  *
  4.  * All rights granted to John Walker (who then promptly placed them
  5.  * in the public domain--JW).
  6.  *
  7.  * History:
  8.  * 12/12/1995    HP Audio Server version 1
  9.  */
  10.  
  11. #include "speakfree.h"
  12.  
  13. #ifdef HEWLETT_PACKARD
  14.  
  15. /* #define HP_DEBUG */             /* Enable debug I/O */
  16.  
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <fcntl.h>
  20. #include <audio/Alib.h>
  21.  
  22. #define SAMPLING_RATE    8000
  23. #define SAMPLE_FORMAT    ADFMuLaw
  24. #define BITS_PER_SAMPLE 8
  25.  
  26. #define STATE_RECORD_NEXT_TIME    1
  27. #define STATE_EMPTY        2
  28.  
  29. static Audio* Audio_Dev = NULL;     /* Pointer to open audio    */
  30. static SBucket* Sound_Buck = NULL;    /* Sound bucket for audio    */
  31. static long   Audio_Error;        /* Status value for audio cmds    */
  32. static SBPlayParams  Play_Params;    /* Play parameters        */
  33. static SBRecordParams Rec_Params;    /* Record parameters        */
  34. static AGainEntry Out_Gain_Entries;    /* Play gain entries        */
  35. static AGainEntry In_Gain_Entries;    /* Record gain entries        */
  36. static ATransID Trans_Id;        /* Audio transaction ID     */
  37. static unsigned long Read_Begin = 0;    /* Current begin in rec bucket    */
  38. static int Read_State = STATE_RECORD_NEXT_TIME; /* Read state        */
  39.  
  40. int HPTermHookChar = 0;         /* Must hook into mike to do it */
  41. int Term_Char = 0;
  42.  
  43. /* hpAudioHandler - HP audio exception handler
  44.  */
  45. static long hpAudioHandler(audio, event)
  46.     Audio* audio;
  47.     AErrorEvent* event;
  48. {
  49.     fprintf(stderr, "Audio error %ld\n", event->error_code);
  50.     exit(1);
  51. }
  52.  
  53. /* soundinit - Initialize sound.
  54.  *
  55.  * iomode is either O_RDONLY for mike or O_WRONLY for speaker
  56.  */
  57. int soundinit(iomode)
  58.     int iomode;
  59. {
  60.     AudioAttrMask attr_mask;
  61.     AudioAttributes audio_attr;
  62.  
  63.     (void)ASetErrorHandler(hpAudioHandler);
  64.  
  65.     Audio_Dev = AOpenAudio(NULL, NULL);
  66.  
  67.     ASetCloseDownMode(Audio_Dev, AKeepTransactions, NULL);
  68.  
  69.     audio_attr.attr.sampled_attr.sampling_rate     = SAMPLING_RATE;
  70.     audio_attr.attr.sampled_attr.data_format     = SAMPLE_FORMAT;
  71.     audio_attr.attr.sampled_attr.bits_per_sample = BITS_PER_SAMPLE;
  72.     audio_attr.attr.sampled_attr.channels     = 1;
  73.  
  74.     attr_mask = (ASDataFormatMask | ASBitsPerSampleMask | ASSamplingRateMask |
  75.          ASChannelsMask);
  76.  
  77.     Sound_Buck = ACreateSBucket(Audio_Dev, attr_mask, &audio_attr, NULL);
  78.  
  79.     Out_Gain_Entries.u.o.out_ch = AOCTMono;
  80.     Out_Gain_Entries.u.o.out_dst = AODTMonoIntSpeaker;
  81.     Out_Gain_Entries.gain = AMaxOutputGain(Audio_Dev);
  82.  
  83.     Play_Params.gain_matrix.type = AGMTOutput;
  84.     Play_Params.gain_matrix.num_entries = 1;
  85.     Play_Params.gain_matrix.gain_entries = &Out_Gain_Entries;
  86.     Play_Params.play_volume = AUnityGain;
  87.     Play_Params.pause_first = False;
  88.     Play_Params.start_offset.type = ATTSamples;
  89.     Play_Params.start_offset.u.samples = 0;
  90.     Play_Params.duration.type = ATTFullLength;
  91.     Play_Params.loop_count = 1;
  92.     Play_Params.priority = APriorityUrgent;
  93.     Play_Params.previous_transaction = 0;
  94.     Play_Params.event_mask = 0;
  95.  
  96.     In_Gain_Entries.u.i.in_ch = AICTMono;
  97.     In_Gain_Entries.u.i.in_src = AISTMonoMicrophone;
  98.     In_Gain_Entries.gain = AMaxInputGain(Audio_Dev);
  99.     
  100.     Rec_Params.gain_matrix.type = AGMTInput;
  101.     Rec_Params.gain_matrix.num_entries = 1;
  102.     Rec_Params.gain_matrix.gain_entries = &In_Gain_Entries;
  103.     Rec_Params.record_gain = AUnityGain;
  104.     Rec_Params.start_offset.type = ATTSamples;
  105.     Rec_Params.start_offset.u.samples = 0;
  106.     Rec_Params.duration.type = ATTFullLength;
  107.     Rec_Params.event_mask = ATransCompletedMask | ATransStoppedMask;
  108. }
  109.  
  110. /* soundterm - close the sounddevice.
  111.  */
  112. void soundterm()
  113. {
  114.     if (Sound_Buck) {
  115.     ADestroySBucket(Audio_Dev, Sound_Buck, NULL);
  116.     Sound_Buck = NULL;
  117.     }
  118.  
  119.     if (Audio_Dev) {
  120.     ACloseAudio(Audio_Dev, NULL);
  121.     Audio_Dev = NULL;
  122.     }
  123. }
  124.  
  125. /* soundplay - begin playing a sound.
  126.  */
  127. void soundplay(len, buf)
  128.     int len;
  129.     unsigned char* buf;
  130. {
  131.     unsigned long bytes_to_put = len;
  132.     unsigned long bytes_put;
  133.     
  134.     while (bytes_to_put) {
  135.     bytes_put = APutSBucketData(Audio_Dev, Sound_Buck, 0, (char*)buf,
  136.                     bytes_to_put, &Audio_Error);
  137.     if (Audio_Error)
  138.         break;
  139.     bytes_to_put -= bytes_put;
  140.     APlaySBucket(Audio_Dev, Sound_Buck, &Play_Params, NULL);
  141.     }
  142. }
  143.  
  144. /* soundplayvol - set playback volume from 0 (silence) to 100 (full on).
  145.  */
  146. void soundplayvol(value)
  147.     int value;
  148. {
  149.     ;
  150. }
  151.  
  152. /* soundrecgain - set recording gain from 0 (minimum) to 100 (maximum).
  153.  */
  154. void soundrecgain(value)
  155.     int value;
  156. {
  157.     ;
  158. }
  159.  
  160. /* sounddest - set destination for generated sound.
  161.  *
  162.  * where = 0, goes to built-in speaker
  163.  *     = 1, goes to the audio output jack
  164.  */
  165. void sounddest(where)
  166.     int where;
  167. {
  168.     if (where == 0)
  169.     Out_Gain_Entries.u.o.out_dst = AODTMonoIntSpeaker;
  170.     else
  171.     Out_Gain_Entries.u.o.out_dst = AODTMonoJack;
  172. }
  173.  
  174. static int WaitForTermination()
  175. {
  176.     int stdin_fd = fileno(stdin);
  177.     int max_fd = aConnectionNumber(Audio_Dev);
  178.     int num_ready;
  179.     int c;
  180.  
  181.     fd_set sel_fds;
  182.  
  183.     if (stdin_fd > max_fd)
  184.     max_fd = stdin_fd;
  185.  
  186.     FD_ZERO(&sel_fds);
  187.     FD_SET(stdin_fd, &sel_fds);
  188.     FD_SET(aConnectionNumber(Audio_Dev), &sel_fds);
  189.     
  190.     num_ready = select( max_fd + 1, (int*)&sel_fds, NULL, NULL, NULL);
  191.     if (num_ready < 0) {
  192.         fprintf(stderr, "select failed\n");
  193.     return 0;
  194.     }
  195.  
  196.     if (FD_ISSET(stdin_fd, &sel_fds))
  197.     Term_Char = getchar();
  198.  
  199.     if (FD_ISSET(aConnectionNumber(Audio_Dev), &sel_fds)) {
  200.     AEvent Event;
  201.     while (AQLength(Audio_Dev) > 0) {
  202.         ANextEvent(Audio_Dev, Event, NULL);
  203. #ifdef HP_DEBUG
  204.             printf("Audio event type %ld\n", Event.type);
  205. #endif
  206.     }
  207.  
  208.     return 1;
  209.     }
  210.  
  211.     return 0;
  212. }
  213.  
  214. /* soundgrab - return audio information in the record queue.
  215.  */
  216. int soundgrab(buf, len)
  217.     char* buf;
  218.     int len;
  219. {
  220.     unsigned long bytes_read;
  221.  
  222.     if (Read_Begin == 0) {
  223.  
  224.     /* Read buffer is empty for the first time */
  225.     if (Read_State == STATE_EMPTY) {
  226.         Read_State = STATE_RECORD_NEXT_TIME;
  227.         HPTermHookChar = 0;
  228.         return 0;
  229.     }
  230.  
  231. #ifdef HP_DEBUG
  232.         printf("Recording bucket\n");
  233. #endif
  234.     Trans_Id = ARecordAData(Audio_Dev, Sound_Buck, Rec_Params, NULL);
  235.     if (WaitForTermination() == 0) {
  236. #ifdef HP_DEBUG
  237.             printf("Manually terminated\n");
  238. #endif
  239.         AStopAudio(Audio_Dev, Trans_Id, ASMThisTrans, NULL, NULL);
  240.     }
  241.     }
  242.  
  243.     bytes_read = AGetSBucketData(Audio_Dev, Sound_Buck, Read_Begin,
  244.                  buf, (unsigned long)len, NULL);
  245.  
  246. #ifdef HP_DEBUG
  247.     printf("%ld bytes got from position %ld in bucket\n", bytes_read, Read_Begin);
  248. #endif
  249.  
  250.     if (bytes_read == 0) {
  251.  
  252.     /* Ok, here we stop to return something */
  253.  
  254.     Read_Begin = 0L;
  255.     Read_State = STATE_EMPTY;
  256.     HPTermHookChar = Term_Char;
  257.  
  258.     } else {
  259.     Read_Begin += bytes_read;
  260.     }
  261.  
  262.     return (int)bytes_read;
  263. }
  264.  
  265. /* soundflush - flush any queued sound.
  266.  */
  267. void soundflush()
  268. {
  269.     ;
  270. }
  271.  
  272. /* Brian Abernathy supplied the following emulation of gethostid(),
  273.    which is not implemented on HPUX at present.  */
  274.  
  275. gethostid()
  276. {
  277.     struct utsname utname;
  278.  
  279.     uname(utname);
  280.     return (unsigned long) atoi(utname.idnumber);
  281. }
  282. #endif
  283.